'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Created by Wang on 2018/7/4.
 */
var NodeTreeView = function () {
    function NodeTreeView() {
        _classCallCheck(this, NodeTreeView);

        this.g = null;
        this.selectedNode = undefined;
        this.fromEdge = undefined;
        this.collapsed = [];
    }

    _createClass(NodeTreeView, [{
        key: 'iterate',
        value: function iterate(rootId, nodeId) {
            if (rootId === nodeId) {
                this.collapsed.push(nodeId);
                return true;
            }
            var edges = [].concat(_toConsumableArray(this.g.edges)).filter(function (edge) {
                return !edge.$removed && edge.from === rootId;
            });
            for (var i = 0; i < edges.length; i++) {
                var found = false;

                if (edges[i].to === nodeId) {
                    found = true;
                } else {
                    found = this.iterate(edges[i].to, nodeId);
                }

                if (found === true) {
                    this.collapsed.push(edges[i].to);
                    return true;
                }
            }
            return false;
        }
    }, {
        key: 'collapseTo',
        value: function collapseTo(node) {
            this.iterate(this.g.getRoot(), node);
        }
    }, {
        key: 'collapseAll',
        value: function collapseAll() {
            var _this = this;

            this.collapsed = [];
            [].concat(_toConsumableArray(this.g.nodes.values())).forEach(function (node) {
                return _this.collapsed.push(node.id);
            });
        }
    }, {
        key: 'getRoot',
        value: function getRoot() {
            var root = this.g.getRoot();
            return root;
        }
    }, {
        key: 'getLinks',
        value: function getLinks(id) {
            var _this2 = this;

            // console.log('GetLinks of '+id);
            var node = this.g.getNode(id);
            var edges = node == null ? [] : node.getLinks(this.g).sort(function (edge1, edge2) {
                var targetNode1 = _this2.g.getNode(edge1.to);
                var targetNode2 = _this2.g.getNode(edge2.to);

                return MyNode.compare(targetNode1, targetNode2);
            });
            // console.log('GetLinks of '+id);
            // console.log(edges);
            return edges;
        }
    }]);

    return NodeTreeView;
}();

var treeview2 = angular.module('ui.bootstrap.treeview2', []);
treeview2.directive('treeView', ['$compile', '$templateCache', function ($compile, $templateCache) {
    return {
        restrict: 'E',
        scope: {},
        bindToController: {
            treeService: '='
        },
        controller: function controller() {
            var that = this;

            this.isCollapsed = function (nodeId) {
                return that.treeService.collapsed.indexOf(nodeId) > -1;
            };

            // toggle when icon clicked
            this.toggleNode = function (node) {
                if (node == null) return;
                var links = node.getLinks(this.treeService.g);
                // collapse / expand
                if (links && links.length > 0) {
                    // add the node to our collapsed array
                    var index = that.treeService.collapsed.indexOf(node.id);

                    if (index === -1) that.treeService.collapsed.push(node.id);else that.treeService.collapsed.splice(index, 1);
                }
            };

            // select when name clicked
            this.selectNode = function (e, node, fromEdge) {
                that.treeService.fromEdge = fromEdge;
                that.treeService.selectedNode = node;

                e.stopPropagation();
                e.preventDefault();
            };

            this.hasChildren = function (node) {
                var links = node == null ? [] : node.getLinks(this.treeService.g);
                return links && links.length > 0;
            };

            this.sortByEdgeId = function (edge) {
                return edge.id;
            };
        },
        controllerAs: 'ctrl',
        link: function link(scope, element, attrs, ctrl) {
            var isRoot = !attrs.treeRoot ? true : false;

            var itemInclude = attrs.itemNgInclude || '';
            var nodeRef = attrs.nodeRef;
            var itemIncludeHtml = '';

            if (itemInclude && itemInclude.length > 0) {
                itemIncludeHtml = $templateCache.get(attrs.itemNgInclude);
            }

            element.removeAttr('item-ng-include');
            element.removeAttr('tree-root');

            // template
            var template = '';

            if (isRoot) {
                template = '<ul ng-init="node=ctrl.treeService.getRoot()" >' + '<li drag-accept-node tree-service="ctrl.treeService" node-ref="{{node.id}}">' + '<div ng-click="ctrl.selectNode($event, node, null)" class="node" ng-class="{\'selected\' : node == ctrl.treeService.selectedNode}">' + '<div ng-class="[node.$type]">' + '<i ng-click="ctrl.toggleNode(node)" ng-show="ctrl.hasChildren(node)" ng-class="!ctrl.isCollapsed(node.id) ? \'has-child\' : \'has-child-open\'"></i>' + '<i ng-click="ctrl.toggleNode(node)" class="no-child" ng-show="!ctrl.hasChildren(node)"></i>' + '<span ng-bind="node.getTextWithId()" ng-class="{\'selected\' : node == ctrl.treeService.selectedNode,\'faultMatched\' : node.isMatched,\'faultUnKnown\' : node.unknown}"></span>' + '</div>' + itemIncludeHtml + '</div>' + '<div class="tree-context" ng-class=" \'tree-node-\'+ node.id"><tree-view uib-collapse="!ctrl.isCollapsed(node.id)" tree-service="ctrl.treeService" node-ref="{{node.id}}" tree-root="false" item-ng-include="' + itemInclude + '" ng-class="[node.$type]"></tree-view></div>' + '</li>' + '</ul>';
            } else {
                template = '<ul >' + '<li  ng-repeat="edge in ctrl.treeService.getLinks(\'' + nodeRef + '\') track by edge.id " ng-if="!edge.$removed" ng-init="node=ctrl.treeService.g.getNode(edge.to)" ng-class="{\'fault-is-subgraph\':(node.$is_sub_graph || node.$is_sub_graph2 )}" >' + '<div drag-accept-node tree-service="ctrl.treeService" node-ref="{{node.id}}" ng-click="ctrl.selectNode($event, node, edge.id)" class="node" ng-class="{\'selected\' : node == ctrl.treeService.selectedNode}">' + '<div drag-tree-node node-ref="{{node.id}}"  ng-class="[node.$type]">' + '<i ng-click="ctrl.toggleNode(node)" ng-show="ctrl.hasChildren(node)" ng-class="!ctrl.isCollapsed(node.id) ? \'has-child\' : \'has-child-open\'"></i>' + '<i ng-click="ctrl.toggleNode(node)" class="no-child" ng-show="!ctrl.hasChildren(node)"></i>' + '<span ng-bind="node.getTextWithId()" node-ref="{{node.id}}" ng-class="{\'selected\' : node == ctrl.treeService.selectedNode,\'faultFreedom\':node.$freedom,\'faultMatched\' : node.isMatched,\'faultUnKnown\' : node.unknown}"></span>' + '</div>' + itemIncludeHtml + '</div>' + '<div class="tree-context" ng-class=" \'tree-node-\'+ node.id"><tree-view uib-collapse="!ctrl.isCollapsed(node.id)" tree-service="ctrl.treeService" node-ref="{{node.id}}" tree-root="false" item-ng-include="' + itemInclude + '" ng-class="[node.$type]"></tree-view></div>' + '</li>' + '</ul>';
            }

            if (!isRoot) {
                template = template.replace('[REPLACENODES]', '$parent.node.children');
            } else {
                template = template.replace('[REPLACENODES]', 'ctrl.treeService.getRoot()');
            }

            var compiledHtml = $compile(template)(scope);

            element.append(compiledHtml);
        }
    };
}]);

treeview2.directive('dragTreeNode', ['$compile', '$templateCache', function ($compile, $templateCache) {
    return {
        restrict: 'A',
        scope: {},
        bindToController: {
            treeService: '='
        },
        controller: function controller() {
            var that = this;
        },
        controllerAs: 'ctrl',
        link: function link(scope, element, attrs, ctrl) {
            var nodeRef = attrs.nodeRef;
            element.attr('draggable', true);
            element.on("dragstart", function (e) {
                e.originalEvent.dataTransfer.setData("Text", nodeRef);
            });
        }
    };
}]);

treeview2.directive('dragAcceptNode', ['$compile', '$templateCache', function ($compile, $templateCache) {
    return {
        restrict: 'A',
        scope: {},
        bindToController: {
            treeService: '='
        },
        controller: function controller() {
            var that = this;
        },
        controllerAs: 'ctrl',
        link: function link(scope, element, attrs, ctrl) {
            var nodeRef = attrs.nodeRef;

            element.on("dragover", function (e) {
                e.preventDefault();
            });
            element.on("drop", function (e) {
                e.preventDefault();
                e.stopPropagation();
                var sourceNode = ctrl.treeService.g.getNode(e.originalEvent.dataTransfer.getData("Text"));
                var targetNode = ctrl.treeService.g.getNode(nodeRef);
                console.info({
                    from: e.originalEvent.dataTransfer.getData("Text"),
                    to: nodeRef,
                    e: e,
                    source: sourceNode.getText(),
                    target: targetNode.getText()
                });

                var dropPair = targetNode.$type + '->' + sourceNode.$type;
                if (dropEnableList.indexOf(dropPair) >= 0) {
                    // let newNode = jQuery.extend(true,sourceNode,{
                    //     $state:'new',
                    //     id:MyNode.idGenerator++
                    // });
                    // ctrl.treeService.g.addNode(newNode);
                    // ctrl.treeService.g.addLink(targetNode.id,newNode.id);
                    ctrl.treeService.g.addLink(targetNode.id, sourceNode.id);
                    alert("复制链接成功！");
                }
            });
        }
    };
}]);

var dropEnableList = ['Fault->Feature', 'Fault->Reason', 'Fault->FeatureGroup', 'Fault->ReasonGroup', 'Feature->Component', 'Feature->ComponentGroup', 'Reason->Component', 'Reason->ReasonGroup', 'FeatureGroup->Feature', 'FeatureGroup->FeatureGroup', 'ReasonGroup->Reason', 'ReasonGroup->ReasonGroup', 'ComponentGroup->Component'];
